#![doc = "../README.md"]

use std::{rc::Rc, result};

pub mod comptime;
pub mod expr;
pub mod runtime;
pub mod custom_parsing;
mod token;

#[cfg(test)]
mod test;

pub use comptime::{parse, parse_exprs, Lexer, Parser};
pub use expr::Expr;
pub use runtime::{Env, EvalResult, Value, Appliable};
pub use token::Token;
pub use custom_parsing::{eval_to, parse_to, EvalFromExpr, ParseFromExpr};

#[cfg(feature = "builtin")]
pub mod builtin {
    pub use dj_builtin::builtin;
    pub use dj_codegen::builtin_method;
    pub mod dependency {
        pub use crate::{
            runtime::{EnvExt, EvalResult},
            Env, Error, Expr, Value,
        };
        pub use std::rc::Rc;
    }
}

#[derive(Debug, thiserror::Error)]
pub enum Error {
    #[error("Comptime Error: {0}")]
    Interpret(#[from] comptime::Error),
    #[error("Runtime Error: {0}")]
    Runtime(#[from] runtime::Error),
    #[error("Custom Parsing: {0}")]
    CustomParsing(#[from] custom_parsing::Error)
}

pub type Result<T> = result::Result<T, Error>;
pub type BuiltinMacro = fn(Rc<Env>, Vec<Expr>) -> EvalResult;

pub const fn version() -> &'static str {
    env!("CARGO_PKG_VERSION")
}